﻿#ifndef WRWORKTCPCOMMCLIENTEVENTSOURCE
#define WRWORKTCPCOMMCLIENTEVENTSOURCE

#include "WRWorkTcpCommClientInterface.h"
#include "WRWorkTcpCommClientInterfaceActivator.h"
#include "../WRWorkTcpComm.h"
#include "../WRWorkTcpCommConsts.h"
#include "../../WRSoft-Utility/Framing/WREventHandlers.h"
#include "../../WRSoft-Utility/Runtime/WRDataPacket.h"

/********************
class Parser
{
public:
    bool parse(const unsigned char* buf, int len, T& val);
};
********************/

//表示工作TCP通讯客户端事件源接口。
template <class T, class TParser>
class WRWorkTcpCommClientEventSource : public WRWorkTcpCommClientInterface, public WREventHandlers<T>
{
private:
    TParser m_parser;

protected:
    //当指定的观察者添加前调用此方法。
    void onAdding(WRObservers<WREventHandler>::Observer observer)
    {
        WREventHandlers<T>::onAdding(observer);
        if (WRObservers<WREventHandler>::m_count == 0)
        {
            WRWorkTcpCommClientSession* session = object()->session();
            if (session->effective())
            {
                WRDataPacket* packet;
                if (affair())
                {
                    char* p;
                    packet = WRDataPacket::allocate<32>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(32), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectAffair, p + 10);//类型（工作事务）
                    WRBytes::write((WR32s)(affair()->id()), p + 12);
                    WRBytes::write((WR16u)(affair()->index()), p + 16);//工作事务索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkAffairIITreat, p + 18);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 20);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::EventStarted, p + 22);//动作
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 24);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 28);//帧尾
                }
                else
                {
                    char* p;
                    packet = WRDataPacket::allocate<24>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(24), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIITreat, p + 10);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 12);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::EventStarted, p + 14);//动作
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 16);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 20);//帧尾
                }
                if (!session->sendData(packet))
                {
                    packet->release();
                }
            }
        }
    }
    //当指定的观察者移除后调用此方法。
    void onRemoved(WRObservers<WREventHandler>::Observer observer)
    {
        if (WRObservers<WREventHandler>::m_count == 0)
        {
            WRWorkTcpCommClientSession* session = object()->session();
            if (session->effective())
            {
                WRDataPacket* packet;
                if (affair())
                {
                    char* p;
                    packet = WRDataPacket::allocate<32>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(32), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectAffair, p + 10);//类型（工作事务）
                    WRBytes::write((WR32s)(affair()->id()), p + 12);
                    WRBytes::write((WR16u)(affair()->index()), p + 16);//工作事务索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkAffairIITreat, p + 18);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 20);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::EventStopped, p + 22);//动作
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 24);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 28);//帧尾
                }
                else
                {
                    char* p;
                    packet = WRDataPacket::allocate<24>();
                    packet->buffer(&p);

                    WRBytes::write((WR32u)WRWorkTcpComm::FrameHeader, p);//帧头
                    WRBytes::write((WR32s)(24), p + 4);//帧长度
                    WRBytes::write((WR16u)(object()->index()), p + 8);//工作对象索引
                    WRBytes::write((WR16u)WRWorkTcpComm::WorkObjectIITreat, p + 10);//类型（处理）
                    WRBytes::write((WR16u)(index()), p + 12);//索引
                    WRBytes::write((WR16u)WRWorkTcpComm::EventStopped, p + 14);//动作
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameVersion, p + 16);//版本
                    WRBytes::write((WR32u)WRWorkTcpComm::FrameTailor, p + 20);//帧尾
                }
                if (!session->sendData(packet))
                {
                    packet->release();
                }
            }
        }
        WREventHandlers<T>::onRemoved(observer);
    }

public:
    //初始化工作TCP通讯客户端事件源接口。
    WRWorkTcpCommClientEventSource(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommClientObject* target)
        : WRWorkTcpCommClientInterface(uuid, name, index, target)
    {
        //add code here
    }
    //初始化工作TCP通讯客户端事件源接口。
    WRWorkTcpCommClientEventSource(const QUuid& uuid, const QString& name, int index, WRWorkTcpCommClientAffair* target)
        : WRWorkTcpCommClientInterface(uuid, name, index, target)
    {
        //add code here
    }

    //清理当前对象所占用的相关资源。
    ~WRWorkTcpCommClientEventSource(void)
    {
        //add code here
    }

    //创建当前接口的新接口。
    WRWorkTcpCommClientInterface* clone(WRWorkTcpCommClientObject* target)
    {
        return new WRWorkTcpCommClientEventSource(uuid(), name(), index(), target);
    }
    //创建当前接口的新接口。
    WRWorkTcpCommClientInterface* clone(WRWorkTcpCommClientAffair* target)
    {
        return new WRWorkTcpCommClientEventSource(uuid(), name(), index(), target);
    }

    //处理数据。
    void procData(const unsigned char* buf, int len)
    {
        WR16u cmdType = WRBytes::read<WR16u>(buf);
        buf += 2;
        len -= 2;
        switch(cmdType)
        {
        case WRWorkTcpComm::EventProcess:// 事件源
        {
            buf += 4;
            len -= 4;
            WR32s cnt = WRBytes::read<WR32s>(buf);
            buf += 4;
            len -= 4;
            if (cnt <= len)
            {
                T val;
                if (m_parser.parse(buf, cnt, val))
                {
                    doProcess(&val);
                }
                else
                {
                    //add code here to process on parsing failed!
                }
            }
            else
            {
                //add code here to process on message error!
            }
        }
            break;
        default:
            break;
        }
    }

    //获取事件源接口。
    WREventSource* eventSource(void)
    {
        return this;
    }
};

//表示工作TCP通讯客户端事件源激活器。
template <class T, class TParser, class TUuidValue, class TNameValue>
class WRWorkTcpCommClientEventSourceActivator : public WRWorkTcpCommClientInterfaceActivator
{
public:
    //初始化工作TCP通讯客户端事件源激活器。
    WRWorkTcpCommClientEventSourceActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::enrollClientInterface(uuid(), this);
    }
    //释放当前对象所占用的相关资源。
    ~WRWorkTcpCommClientEventSourceActivator(void)
    {
        TUuidValue uuid;
        WRWorkTcpComm::cancelClientInterface(uuid());
    }

    //创建接口实例。
    WRWorkTcpCommClientInterface* create(int index, WRWorkTcpCommClientObject* target)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommClientEventSource<T, TParser>(uuid(), name(), index, target);
    }
    //创建接口实例。
    WRWorkTcpCommClientInterface* create(int index, WRWorkTcpCommClientAffair* target)
    {
        TUuidValue uuid;
        TNameValue name;
        return new WRWorkTcpCommClientEventSource<T, TParser>(uuid(), name(), index, target);
    }
};

#endif // WRWORKTCPCOMMCLIENTEVENTSOURCE

